// PreferencesService.cs
// Facebook/Framework/Service
// Copyright (c) 2007, Nikhil Kothari. All Rights Reserved.
//

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using Facebook.Service.Core;

namespace Facebook.Service {

    /// <summary>
    /// Represents the service APIs that allow retrieving and persisting user settings.
    /// </summary>
    public sealed class PreferencesService {

        private FacebookSession _session;

        internal PreferencesService(FacebookSession session) {
            Debug.Assert(session != null);
            _session = session;
        }

        /// <summary>
        /// Loads the preferences for the current user.
        /// </summary>
        /// <returns>The UserPreferences object with current values for the user.</returns>
        public UserPreferences LoadPreferences() {
            return LoadPreferences(null);
        }

        /// <summary>
        /// Loads the preferences for the current user into a UserPreferences object
        /// of the specified type.
        /// </summary>
        /// <param name="preferencesObjectType">The type of UserPreferences object to create.</param>
        /// <returns>The UserPreferences object with current values for the user.</returns>
        public UserPreferences LoadPreferences(Type preferencesObjectType) {
            UserPreferences preferences = null;

            if (preferencesObjectType == null) {
                preferences = new UserPreferences();
            }
            else {
                if (typeof(UserPreferences).IsAssignableFrom(preferencesObjectType) == false) {
                    throw new ArgumentException("Preferences object type must derive from UserPreferences.", "preferencesObjectType");
                }
                preferences = (UserPreferences)Activator.CreateInstance(preferencesObjectType);
            }

            FacebookRequest request = new FacebookRequest(_session);
            FacebookResponse response = request.InvokeMethod("data.getUserPreferences");

            if (response.Status == FacebookResponseStatus.Succeeded) {
                if (response.Result is ArrayList) {
                    preferences.Load((ArrayList)response.Result);
                }
            }

            return preferences;
        }

        /// <summary>
        /// Saves the specified preferences. The settings in the preferences object
        /// replace the current settings associated with the user.
        /// </summary>
        /// <param name="preferences">The preferences to be saved.</param>
        /// <returns>true if the values were successfully saved; false otherwise.</returns>
        public bool SavePreferences(UserPreferences preferences) {
            return SavePreferences(preferences, /* replace */ true);
        }

        /// <summary>
        /// Saves the specified preferences. The settings can either be merged into
        /// the current set of settings, or can be used to replace the current settings.
        /// </summary>
        /// <param name="preferences">The preferences to be saved.</param>
        /// <param name="replace">Whether to use the specified preferences to replace current values or to merge them in.</param>
        /// <returns>true if the values were successfully saved; false otherwise.</returns>
        public bool SavePreferences(UserPreferences preferences, bool replace) {
            if (preferences == null) {
                throw new ArgumentNullException("preferences");
            }

            FacebookRequest request = new FacebookRequest(_session);
            request.Parameters["replace"] = replace ? "1" : "0";
            request.Parameters["values"] = preferences.Save(replace);

            FacebookResponse response = request.InvokeMethod("data.setUserPreferences");
            if (response.Status == FacebookResponseStatus.Succeeded) {
                return true;
            }

            return false;
        }
    }
}
